package cn.good.yan.service.t4;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Geo 地理空间  - 演示
 *
 * @author shengren.yan
 * @create 2023-11-21
 */
@Service
@Slf4j
public class GeoServiceImpl {

    @Autowired
    private RedisTemplate redisTemplate;
    public static final String CITY = "city";

    // 添加坐标
    public String geoAdd() {
        Map<String, Point> map = new HashMap<>();
        map.put("北京站", new Point(116.451412,39.909179));
        map.put("故宫", new Point(116.403263,39.923706));
        map.put("御花园", new Point(116.402903,39.927773));
        map.put("故宫大门", new Point(116.403406,39.920248));
        map.put("什刹海", new Point(116.393345,39.948574));
        map.put("欢乐谷", new Point(116.502004,39.874635));
        redisTemplate.opsForGeo().add(CITY, map);
        return "ok";
    }

    // 获取经纬度坐标 ， 参数就是 member 就是 map里的key  - 支持查多个
    public Point position(String member) {
        List<Point> position = redisTemplate.opsForGeo().position(CITY, member);
        List<Point> position2 = redisTemplate.opsForGeo().position(CITY, "北京站", "故宫");
        System.out.println(position2);
        double x = position2.get(0).getX();
        double y = position2.get(0).getY();
        System.out.println(x + " : " + y);
        return position.get(0);
    }

    // 获取经纬度生成的base32编码值geohash
    public String hash(String member) {
        List<String> hash = redisTemplate.opsForGeo().hash(CITY, member);
        return hash.get(0);
    }

    // 获取两个位置之间的距离
    public Distance distance(String member1, String member2) {
        // 获取两个位置之间的距离  KILOMETERS 千米
        Distance distance = redisTemplate.opsForGeo().distance(CITY, member1, member2,
                RedisGeoCommands.DistanceUnit.KILOMETERS);

        return distance;
    }

    // 查找 根据某个坐标位置，显示附近有哪些
    public GeoResults radiusByxy() {
        // 通过经纬度查找附近的，紫禁城的位置 116.407503,39.928686 ， KILOMETERS 单位：千米，公里
        Circle circle = new Circle(116.407503,39.928686, Metrics.KILOMETERS.getMultiplier());
        // 返回10条
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                .includeCoordinates()
                // sortDescending 降序
                .sortDescending()
                // 返回10条
                .limit(10);

        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, circle, args);
//   泛型写法     GeoResults geoResults1 = redisTemplate.opsForGeo().radius(CITY, circle, args);

        System.out.println(geoResults);
        return geoResults;
    }

    // 查找 根据某个坐标位置，显示附近有哪些
    public GeoResults radiusMember() {
        String member = "故宫";
        // 返回10条
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                .includeDistance().sortAscending().limit(10);
        // 半径 1 公里内
        Distance distance = new Distance(1, Metrics.KILOMETERS);
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, member, distance, args);

        System.out.println(geoResults);
        return geoResults;
    }


}
